package com.tangbuzhi.adapter;

/**
 * 适配器模式
 */
public class Adapter {
    public static class Source {
        public void originalMethod() {
            System.out.println("this is original method");
        }
    }

    public interface Targetable {
        void originalMethod();

        void newMethod();
    }

    /**
     * 类适配器模式：类适配器模式主要是适配器类要继承Source类，并实现拓展接口（要求拓展接口中必须要有与Source类一样的method,并拓展了newMethod）
     */
    public static class SourceAdapter extends Source implements Targetable {
        @Override
        public void newMethod() {
            System.out.println("this is class adapter new method");
        }
    }

    /**
     * 对象适配器模式：与类适配器模式一样，不同的是，对象适配器模式不再试继承Source类实现Targetable接口了，而是持有Source的实例，并让Source实例去调用原有method
     */
    public static class Wrapper implements Targetable {
        private Source source;

        public Wrapper(Source source) {
            this.source = source;
        }

        @Override
        public void originalMethod() {
            source.originalMethod();
        }

        @Override
        public void newMethod() {
            System.out.println("this is target adapter new method");
        }
    }

    /**
     * 接口适配器模式：主要是为了不必要的接口方法，引入额外的类，该类实现接口，并全部重新接口方法；然后目标类只需要继承该类，重写需要的方法即可
     */
    public interface Sourceable {
        void method1();

        void method2();
    }

    public static abstract class SourceableWrapper implements Sourceable {
        @Override
        public void method1() {
        }

        @Override
        public void method2() {
        }
    }

    public static class Stub1 extends SourceableWrapper {
        @Override
        public void method1() {
            super.method1();
            System.out.println("this is interface adapter first method");
        }
    }

    public static class Stub2 extends SourceableWrapper {
        @Override
        public void method2() {
            super.method2();
            System.out.println("this is interface adapter second method");
        }
    }

    public static void main(String[] args) {
        Targetable targetable = new SourceAdapter();
        targetable.originalMethod();
        targetable.newMethod();

        System.out.println("==============below is target adapter method================");
        Source source = new Source();
        Targetable wrapper = new Wrapper(source);
        wrapper.originalMethod();
        wrapper.newMethod();

        System.out.println("==============below is interface adapter method================");
        Sourceable sourceable1 = new Stub1();
        sourceable1.method1();
        sourceable1.method2();//void

        Sourceable sourceable2 = new Stub2();
        sourceable2.method1();//void
        sourceable2.method2();
        /**输出结果：
         this is original method
         this is class adapter new method
         ==============below is target adapter method================
         this is original method
         this is target adapter new method
         ==============below is interface adapter method================
         this is interface adapter first method
         this is interface adapter second method
         */
    }
}
